package org.zjvis.datascience.common.constant;

import com.alibaba.fastjson.JSONObject;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @description SQL模板拼接常量
 * @date 2021-12-24
 */
public class SqlTemplate {

    public static final String SCHEMA = "pipeline";

    public static final String SOURCE_SCHEMA = "dataset";

    public static final String CREATE_VIEW_SQL = "CREATE VIEW %s AS %s";

    public static final String CREATE_TABLE_SQL = "CREATE TABLE %s AS %s";

    // view_(pipelineID)_(taskId)_(timestamp)
    public static String VIEW_TABLE_NAME = "pipeline.view_%s_%s_";

    // SOLID_(out_table)_(pipelineID)_(taskId)_(timestamp)
    public static String OUT_TABLE_NAME = "pipeline.solid_%s_%s_%s_";

    public static String OUT_METRICS_PATH = "ml_model.solid_%s_%s_%s_";

    /**
     * rename columns like: table.columnName ->   a.column_name as a_columnName
     *
     * @param columns
     * @param key
     * @return
     */
    public static List<String> columnsRenameSql(List<String> columns, String key) {
        return columnsRenameSql(columns, key, null, null);
    }

    public static List<String> columnsRenameSql(List<String> columns, String key,
                                                Set<String> reserveKeys, List<String> otherKeys) {
        return columns.stream().map(x -> {
            if (reserveKeys != null) {
                String[] tmps = x.split("\\.");
                String tmpKey = tmps[tmps.length - 1];
                if (reserveKeys.contains(tmpKey)) {
                    return String.format("%s.\"%s\" as \"%s\"", key, tmpKey, tmpKey);
                }
            }
            String[] tmps = x.split("\\.");
            String tmpKey = tmps[tmps.length - 1];
            if (x.contains(".")) {
                String columnName = x.replaceAll(".*\\.", "");
                columnName = String.format("%s.\"%s\"", key, columnName);
                if (otherKeys != null && !otherKeys.contains(tmpKey)) {
                    // 列名不同，无需转换
                    return String.format("%s as \"%s\"", columnName, tmpKey);
                }
                return String.format("%s as \"%s_%s\"", columnName, tmpKey, key);
            } else {
                if (otherKeys != null && !otherKeys.contains(x)) {
                    return String.format("%s.\"%s\" as \"%s\"", key, x, x);
                }
                return String.format("%s.\"%s\" as \"%s_%s\"", key, x, x, key);
            }
        }).collect(Collectors.toList());
    }

    public static List<String> columnsRename(List<String> columns, String key) {
        return columnsRename(columns, key, null, null);
    }

    /**
     * rename column like: table.columnName -> a_columnName
     *
     * @param columns
     * @param key
     * @return
     */
    public static List<String> columnsRename(List<String> columns, String key,
                                             Set<String> reserveKeys, List<String> otherKeys) {
        return columns.stream().map(x -> {
            if (reserveKeys != null) {
                String[] tmps = x.split("\\.");
                String tmpKey = tmps[tmps.length - 1];
                if (reserveKeys.contains(tmpKey)) {
                    return tmpKey;
                }
            }
            String[] tmps = x.split("\\.");
            String tmpKey = tmps[tmps.length - 1];
            if (otherKeys != null && !otherKeys.contains(tmpKey)) {
                return tmpKey;
            }
            return String.format("%s_%s", tmpKey, key);
        }).collect(Collectors.toList());
    }

    /**
     * rename column like: table.columnName -> a_columnName
     *
     * @param columns
     * @param key
     * @return
     */
    public static List<String> columnInfoRename(List<String> columns, String key,
                                                JSONObject semantics, JSONObject numberFormat, JSONObject categoryOrder, List<String> otherKeys) {
        return columns.stream().map(x -> {
            if (otherKeys != null && !otherKeys.contains(x)) {
                return x;
            }
            String newCol = String.format("%s_%s", x, key);
            semantics.put(newCol, semantics.getString(x));
            semantics.remove(x);
            if (numberFormat != null && !numberFormat.isEmpty()) {
                numberFormat.put(newCol, numberFormat.getJSONObject(x));
                numberFormat.remove(x);
            }
            if (categoryOrder != null && categoryOrder.getJSONArray(x) != null) {
                categoryOrder.put(newCol, categoryOrder.getJSONArray(x));
                categoryOrder.remove(x);
            }
            return newCol;
        }).collect(Collectors.toList());
    }

    /**
     * get columns
     *
     * @param columns
     * @return
     */
    public static List<String> getColumns(List<String> columns) {
        return columns.stream().map(x -> {
            if (x.contains(".")) {
                String columnName = x.replaceAll(".*\\.", "");
                return columnName;
            }
            return x;
        }).collect(Collectors.toList());
    }
}